// for Emacs -*- c++ -*-


// private part of MultiMessageQueue


private:
  /** Internal base class for all the message types
   */
  class InternalMessage {
  private:
    // for type, ask the message
    // priority determined by the queue it is sitting in
    
    Message& payload; // this is the message transmited. The payload should be casted 
    // to the correct type based on type field

    int timestamp; // the time when the message got generated

    
  public:
    
    // constructor
    InternalMessage(Message& Payload, int _timestamp) :
      payload(Payload), timestamp(_timestamp) {
    }

    // default constructor
    InternalMessage(void);

    // copy constructor
    InternalMessage(const InternalMessage&);

    
    InternalMessage& operator=(const InternalMessage& aux);

    int GetType(void);

    inline int GetTimestamp() { return timestamp; }

    inline Message& GetPayload(void) { return payload; }

  };

  /** bookkeeping for each type
      used for keeping track of message queues and info about types */
  class TypeBookkeeping {
  private:
    list<InternalMessage> queue;
    int priority; // the priority of this type
    int type; // the type of the message stored here

  public:
    TypeBookkeeping(int _priority, int _type):
      priority(_priority), type(_type){ }
    
    int GetSize(void){ return queue.size(); }
    
    void InsertMessage(InternalMessage& msg){ queue.push_back(msg); }

    // return the next message in the queue
    // it is an error to ask for the next message if none is there
    InternalMessage NextMessage(void);
    
    // return false if no message in the queue of this type
    bool GetTypeInfo(int curr_timestamp, TypeInfo* where);
  };

// debugging  facility
  bool debug;
  const char *dbgMsg;

  // the user provided decision function
  // if NULL, we call our own
  DecisionFunction decFct;

// EventProcessor that implements the decision function
EventProcessorImp& decProcessor;

  // the default Decision Function
  static int defaultDecisionFunction(EventProcessorImp& _obj, TypeInfo* arrayTypeInfo, int num);
    

  // we keep messages grouped on types
  // we use a map based on type to indicate the queue where the types are
  // the map stores the priority of each type as well
  map<int,TypeBookkeeping> typeMap;
 
  int timestamp; // the current timestamp
  int numMessages; // total number of messages in (for efficiency)

  pthread_mutex_t mutex; // mutex to ensure exclusive manipulation of the queue
  pthread_cond_t condVar; // condition variable for the reader



